package com.yungu.swift.system.sys.service.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.github.miemiedev.mybatis.paginator.domain.PageBounds;
import com.github.miemiedev.mybatis.paginator.domain.PageList;
import com.yungu.swift.base.ResponseData;
import com.yungu.swift.base.mapper.IMapper;
import com.yungu.swift.base.model.PageVo;
import com.yungu.swift.base.model.admin.AdminPageParam;
import com.yungu.swift.base.service.impl.BaseServiceImpl;
import com.yungu.swift.constants.CommonConstant;
import com.yungu.swift.system.sys.dao.SysBusinessOrganizationMapper;
import com.yungu.swift.system.sys.dao.SysCompanyMapper;
import com.yungu.swift.system.sys.dao.SysPointSiteCompanyMapper;
import com.yungu.swift.system.sys.dao.SysWayCompanyMapper;
import com.yungu.swift.system.sys.model.dto.SysBusinessCityDto;
import com.yungu.swift.system.sys.model.dto.SysBusinessDto;
import com.yungu.swift.system.sys.model.dto.SysBusinessOrganizationDto;
import com.yungu.swift.system.sys.model.dto.SysCityDto;
import com.yungu.swift.system.sys.model.dto.SysCompanyDto;
import com.yungu.swift.system.sys.model.dto.SysPointSiteCompanyDto;
import com.yungu.swift.system.sys.model.dto.SysWayCompanyDto;
import com.yungu.swift.system.sys.model.vo.BusinessDetailVo;
import com.yungu.swift.system.sys.model.vo.BusinessVo;
import com.yungu.swift.system.sys.service.SysBusinessCityService;
import com.yungu.swift.system.sys.service.SysBusinessOrganizationService;
import com.yungu.swift.system.sys.service.SysWayService;
import com.yungu.swift.utils.MapUtils;
import com.yungu.swift.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * SystemBusinessOrganizationServiceImpl
 **/
@Slf4j
@Service
public class SysBusinessOrganizationServiceImpl extends BaseServiceImpl<SysBusinessOrganizationDto> implements SysBusinessOrganizationService {

    /**
     * 组织机构级别 1  APP级 2 区域代理级 3 公司级
     **/
    public final static Integer ORGANIZATION_TYPE_APP = 1;
    public final static Integer ORGANIZATION_TYPE_REGIONAL_AGENT = 2;
    public final static Integer ORGANIZATION_TYPE_COMPANY = 3;

    /**
     * 跨城业务uuid
     */
    private final static String JOIN_BUSINESS_UUID = "18ea5532a012472ca650a7fa0b2196ad";
    private final static String PARCEL_BUSINESS_UUID = "df146c603bbc4465bb1650e27fad2kka";

    @Autowired
    private SysBusinessOrganizationMapper sysBusinessOrganizationMapper;
    @Autowired
    private SysCompanyMapper sysCompanyMapper;
    @Autowired
    private SysWayCompanyMapper<SysWayCompanyDto> sysWayCompanyMapper;
    @Autowired
    private SysPointSiteCompanyMapper<SysPointSiteCompanyDto> sysPointSiteCompanyMapper;
    @Autowired
    private SysWayService sysWayService;
    @Autowired
    private SysBusinessCityService sysBusinessCityService;

    @Override
    protected IMapper<SysBusinessOrganizationDto> getMapper() {
        return sysBusinessOrganizationMapper;
    }

    @Override
    public ResponseData<Boolean> delete(String uuid) {
        //判断是否为代理商业务，如果为代理商业务，检索该代理商下的公司相同的业务是否存在，有不允许删除。
        SysBusinessOrganizationDto dto = this.sysBusinessOrganizationMapper.list(MapUtils.build("uuid", uuid)).get(0);
        //代理商级别
        if (dto.getLevel().intValue() == ORGANIZATION_TYPE_REGIONAL_AGENT.intValue()) {
            Map<String, Object> params = MapUtils.build(4);
            params.put("status", CommonConstant.STATUS_OPENED);
            params.put("regionalAgentUuid", dto.getOrganizationUuid());
            params.put("businessUuid", dto.getBusinessUuid());
            int companyBusinessCount = sysBusinessOrganizationMapper.getCompanyBussinessCountByAgent(params);
            if (companyBusinessCount > 0) {
                return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "该区域代理下有公司存在该业务，请先关闭公司业务");
            }
        }
        return ResponseData.buildSuccessResponse("删除成功", sysBusinessOrganizationMapper.del(dto) > 0);
    }


    @Override
    public ResponseData<Boolean> add(SysBusinessOrganizationDto dto) {
        //判断是否存在
        Map<String, Object> params = MapUtils.build(4);
        params.put("organizationUuid", dto.getOrganizationUuid());
        params.put("businessUuid", dto.getBusinessUuid());
        List<SysBusinessOrganizationDto> list = sysBusinessOrganizationMapper.list(params);
        if (CollectionUtils.isNotEmpty(list)) {
            log.error("该组织机构的这项业务已经存在，organizationUuid：{}，businessUuid：{}",
                    dto.getOrganizationUuid(), dto.getBusinessUuid());
            return ResponseData.buildErrorResponse(0, "新增失败，业务已存在！");
        }
        dto.setUuid(StringUtils.buildUUID());
        dto.setCreateOn(new Date());
        dto.setCommissionType(SysBusinessOrganizationDto.COMMISSION_TYPE_PERCENT);
        dto.setCommission(0d);
        dto.setStatus(CommonConstant.STATUS_OPENED);
        if (sysBusinessOrganizationMapper.add(dto) > 0) {
            // 跨城业务要同时开通小件
            if (JOIN_BUSINESS_UUID.equals(dto.getBusinessUuid())) {
                dto.setBusinessUuid(PARCEL_BUSINESS_UUID);
                dto.setUuid(StringUtils.buildUUID());
                sysBusinessOrganizationMapper.add(dto);
            }
            return ResponseData.buildSuccessResponse("新增成功", Boolean.TRUE);
        }
        return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "系统异常，新增失败");
    }

    @Override
    public ResponseData<List<BusinessDetailVo>> getBusinessDetail(String organizationUuid, String uuid) {
        Map params = MapUtils.build(4);
        params.put("organizationUuid", organizationUuid);
        params.put("uuid", uuid);
        return ResponseData.buildSuccessResponse(this.sysBusinessOrganizationMapper.getBusinessDetail(params));
    }

    @Override
    @Transactional
    public ResponseData<Boolean> editResource(String businessOrganizationUuid, String resIds, String userUuid, int type) {
        SysBusinessOrganizationDto dto = sysBusinessOrganizationMapper.list(MapUtils.build("uuid", businessOrganizationUuid)).get(0);
        // 跨城分支
        if (type == CommonConstant.BUSINESS_TYPE_POOL) {
            if (ORGANIZATION_TYPE_APP.equals(dto.getLevel())) {
                return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "非法操作：仅限区域代理、公司级别");
            }
            String agentUuid = ORGANIZATION_TYPE_REGIONAL_AGENT.equals(dto.getLevel()) ? dto.getOrganizationUuid() : null;
            String companyUuid = ORGANIZATION_TYPE_COMPANY.equals(dto.getLevel()) ? dto.getOrganizationUuid() : null;
            if (ORGANIZATION_TYPE_COMPANY.equals(dto.getLevel())) {
                //获取代理
                SysCompanyDto companyDto = sysCompanyMapper.list(MapUtils.build("uuid", companyUuid)).get(0);
                if (null == companyDto) {
                    return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "操作失败：获取公司所属代理信息失败");
                }
                agentUuid = companyDto.getRegionalAgentUuid();
            }

            //数据验证 —— 针对代理更新
            if (ORGANIZATION_TYPE_REGIONAL_AGENT.equals(dto.getLevel())) {
                List<SysWayCompanyDto> sysWayCompanyDtos = sysWayCompanyMapper.listUsed(agentUuid, StringUtils
                        .isNotEmpty(resIds) ? Arrays.asList(resIds.split(",")) : null);
                if (CollectionUtils.isNotEmpty(sysWayCompanyDtos)) {
                    String msg = "操作失败！移除以下线路：<br>";
                    for (SysWayCompanyDto wc : sysWayCompanyDtos) {
                        msg += "<" + wc.getOriginName() + "-" + wc.getDestName() + "><br>";
                    }
                    msg += "时出错，线路被分配于底下公司使用中";
                    return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, msg);
                }
            }
            // 更新线路数据
            editWayResource(agentUuid, companyUuid, resIds);
            return ResponseData.buildSuccessResponse("操作成功：数据已保存", Boolean.TRUE);
        }

        // 专快车业务
        Map<String, Object> build = MapUtils.build(4);
        build.put("organizationUuid", dto.getOrganizationUuid());
        build.put("scope", "myself");
        build.put("type", type);
        //旧资源
        List<String> oldResIds = this.sysBusinessOrganizationMapper.getCityResIds(build);
        List<String> tempOldResIds = oldResIds;
        //更新后的资源集合B
        List<String> newResIds = conventToList(resIds);

        //A-B 被删除的资源集合C
        oldResIds.removeAll(newResIds);
        List<String> deleteResIds = oldResIds;
        //B-A 新增的资源集合D
        newResIds.removeAll(tempOldResIds);
        List<String> addResIds = newResIds;
        //代理商级别
        if (dto.getLevel() == ORGANIZATION_TYPE_REGIONAL_AGENT.intValue()) {
            //有被删除的资源
            if (deleteResIds.size() > 0) {
                //查询子的资源集合
                build.put("scope", "child");
                List<String> companyResIds = this.sysBusinessOrganizationMapper.getCityResIds(build);
                List<String> collect = companyResIds.stream().filter(companyResId -> deleteResIds.contains(companyResId))
                        .collect(Collectors.toList());
                if (CollectionUtils.isNotEmpty(collect)) {
                    return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "该代理商下有公司在使用城市;");
                }
            }
        }
        try {
            //删除资源
            if (deleteResIds.size() > 0) {
                Map<String, Object> map = MapUtils.build(4);
                map.put("deleteResIds", deleteResIds);
                map.put("businessOrganizationUuid", businessOrganizationUuid);
                map.put("type", type);
                sysBusinessOrganizationMapper.batchDelCityResource(map);
            }
            //新增资源
            if (addResIds.size() > 0) {
                for (String addResId : addResIds) {
                    SysBusinessCityDto sysBusinessCityDto = new SysBusinessCityDto();
                    sysBusinessCityDto.setUuid(StringUtils.buildUUID());
                    sysBusinessCityDto.setBusinessOrganizationUuid(businessOrganizationUuid);
                    sysBusinessCityDto.setCityUuid(addResId);
                    sysBusinessCityDto.setCreateOn(new Date());
                    sysBusinessCityDto.setStatus(CommonConstant.STATUS_OPENED);
                    sysBusinessCityDto.setCreateBy(userUuid);
                    sysBusinessCityService.add(sysBusinessCityDto);
                }
            }
            return ResponseData.buildSuccessResponse("编辑资源成功", Boolean.TRUE);
        } catch (Exception e) {
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
        return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "系统异常，操作失败");
    }

    private void editWayResource(String agentUuid, String companyUuid, String resIds) {
        //删除旧数据
        Map<String, Object> build = MapUtils.build(4);
        build.put("agentUuid", agentUuid);
        build.put("companyUuid", companyUuid);
        sysWayCompanyMapper.batchDel(build);

        //更新新数据
        List<SysWayCompanyDto> result = new ArrayList<>();
        if (StringUtils.isNotEmpty(resIds)) {
            for (String resId : resIds.split("\\,")) {
                SysWayCompanyDto wayCompanyDto = new SysWayCompanyDto();
                wayCompanyDto.setUuid(StringUtils.buildUUID());
                wayCompanyDto.setWayUuid(resId);
                wayCompanyDto.setCompanyUuid(companyUuid);
                wayCompanyDto.setAgentUuid(agentUuid);
                result.add(wayCompanyDto);
            }
        }
        if(!result.isEmpty()) {
            sysWayCompanyMapper.batchSave(result);
        }
    }

    private void editPointSiteResource(String agentUuid, String companyUuid, String resIds) {
        //删除旧数据
        Map<String, Object> build = MapUtils.build(4);
        build.put("agentUuid", agentUuid);
        build.put("companyUuid", companyUuid);
        sysPointSiteCompanyMapper.batchDel(build);

        //更新新数据
        List<SysPointSiteCompanyDto> result = new ArrayList<>();
        if (StringUtils.isNotEmpty(resIds)) {
            for (String resId : resIds.split("\\,")) {
                SysPointSiteCompanyDto wayCompanyDto = new SysPointSiteCompanyDto();
                wayCompanyDto.setUuid(StringUtils.buildUUID());
                wayCompanyDto.setPointSiteUuid(resId);
                wayCompanyDto.setCompanyUuid(companyUuid);
                wayCompanyDto.setAgentUuid(agentUuid);
                result.add(wayCompanyDto);
            }
            sysPointSiteCompanyMapper.batchSave(result);
        }
    }

    @Override
    @Transactional
    public ResponseData<Boolean> pointSiteEditResource(String businessOrganizationUuid, String resIds) {
        SysBusinessOrganizationDto dto = sysBusinessOrganizationMapper.list(MapUtils.build("uuid", businessOrganizationUuid)).get(0);
        if (ORGANIZATION_TYPE_APP.equals(dto.getLevel())) {
            return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "非法操作：仅限区域代理、公司级别");
        }
        String agentUuid = ORGANIZATION_TYPE_REGIONAL_AGENT.equals(dto.getLevel()) ? dto.getOrganizationUuid() : null;
        String companyUuid = ORGANIZATION_TYPE_COMPANY.equals(dto.getLevel()) ? dto.getOrganizationUuid() : null;
        if (ORGANIZATION_TYPE_COMPANY.equals(dto.getLevel())) {
            //获取代理
            SysCompanyDto companyDto = sysCompanyMapper.list(MapUtils.build("uuid", companyUuid)).get(0);
            if (null == companyDto) {
                return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "操作失败：获取公司所属代理信息失败");
            }
            agentUuid = companyDto.getRegionalAgentUuid();
        }
        // 获取当前已开通的起终点
        List<SysPointSiteCompanyDto> sysPointSiteCompanyDtos = sysPointSiteCompanyMapper.listPointSiteByOrganization(dto.getOrganizationUuid());
        if (CollectionUtils.isNotEmpty(sysPointSiteCompanyDtos)) {
            List<String> usedPointSiteList = sysPointSiteCompanyDtos.stream().map(SysPointSiteCompanyDto::getPointSiteUuid).collect(Collectors.toList());
            usedPointSiteList.removeAll(conventToList(resIds));
            if (CollectionUtils.isNotEmpty(usedPointSiteList)) {
                List<SysWayCompanyDto> sysWayCompanyDtos = sysWayCompanyMapper.listUse(dto.getOrganizationUuid(), usedPointSiteList);
                if (CollectionUtils.isNotEmpty(sysWayCompanyDtos)) {
                    String msg = "操作起终点失败！以下线路正在使用，请优先移除线路。<br>";
                    for (SysWayCompanyDto wc : sysWayCompanyDtos) {
                        msg += "<" + wc.getOriginName() + "-" + wc.getDestName() + "><br>";
                    }
                    return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, msg);
                }
            }
        }
        // 保存起终点数据
        editPointSiteResource(agentUuid, companyUuid, resIds);
        return ResponseData.buildSuccessResponse("操作成功：数据已保存", Boolean.TRUE);
    }

    @Override
    public ResponseData<List<BusinessVo>> getBusiness(Map<String, Object> paramMap) {
        return ResponseData.buildSuccessResponse(this.sysBusinessOrganizationMapper.getBusiness(paramMap));
    }


    @Override
    public ResponseData<List<SysBusinessDto>> getCityBusiness(Map<String, Object> paramMap) {
        return ResponseData.buildSuccessResponse(this.sysBusinessOrganizationMapper.getCityBusiness(paramMap));
    }

    /**
     * 工具类 将逗号分割的字符串转换为list（因为提供的Arrays.asList是定长的不可以做修改操作）
     *
     * @param str
     * @return
     * @author cuixiuyin
     */
    private List<String> conventToList(String str) {
        List<String> result = new ArrayList<>();
        if (StringUtils.isEmpty(str)) {
            return result;
        }
        List<String> now = Arrays.asList(str.split(","));
        result.addAll(now);
        return result;
    }

    @Override
    public ResponseData<List<SysBusinessOrganizationDto>> getCommission(String driverUuid, Integer businessType) {
        return ResponseData.buildSuccessResponse(sysBusinessOrganizationMapper.getCommission(driverUuid, businessType));
    }


    @Override
    public ResponseData<PageVo<BusinessVo>> queryPageAdmin(AdminPageParam adminPageParam) {
        PageBounds pageBounds = new PageBounds(adminPageParam.getPageNum(), adminPageParam.getPageSize());
        Map<String, Object> map = MapUtils.convertObjToMap(adminPageParam);
        String organizationUuid = StringUtils.isEmpty(adminPageParam.getUserCompanyUuid()) ? adminPageParam.getUserAgentUuid() : adminPageParam.getUserCompanyUuid();
        organizationUuid = StringUtils.isEmpty(organizationUuid) ? adminPageParam.getAppid() : organizationUuid;
        map.put("organizationUuid", organizationUuid);
        PageList<BusinessVo> pageList = sysBusinessOrganizationMapper.queryPageAdmin(map, pageBounds);
        PageVo<BusinessVo> pageVo = new PageVo(adminPageParam.getPageNum(), adminPageParam.getPageSize(), pageList.getPaginator().getTotalCount());
        pageVo.setItems(pageList);
        return ResponseData.buildSuccessResponse(pageVo);
    }

    @Override
    public ResponseData<List<SysBusinessDto>> getOrgUuidBusName2BeanMap(Map<String, Object> paramMap) {
        return ResponseData.buildSuccessResponse(sysBusinessOrganizationMapper.getAllBusinessWithOrganization(paramMap));
    }

    @Override
    public ResponseData<List<SysCityDto>> getOrgUuidBusUuidCityName2BeanMap(Map<String, Object> paramMap) {
        return ResponseData.buildSuccessResponse(sysBusinessOrganizationMapper.getAllCityWithOrganizationBusiness(paramMap));
    }

    @Override
    public ResponseData<SysBusinessOrganizationDto> getPlatformCommission(String driverUuid, Integer businessType) {
        return ResponseData.buildSuccessResponse(sysBusinessOrganizationMapper.getPlatformCommission(driverUuid, businessType));
    }

    @Override
    public ResponseData<SysBusinessOrganizationDto> getAgencyCommission(String driverUuid, Integer businessType) {
        return ResponseData.buildSuccessResponse(sysBusinessOrganizationMapper.getAgencyCommission(driverUuid, businessType));
    }

    @Override
    public ResponseData<SysBusinessOrganizationDto> getCompanyCommission(String driverUuid, Integer businessType) {
        return ResponseData.buildSuccessResponse(sysBusinessOrganizationMapper.getCompanyCommission(driverUuid, businessType));
    }
}
